package com.yenlien.traceyun.control.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yenlien.traceyun.control.dao.BankInfoDao;
import com.yenlien.traceyun.control.dao.BankLevelDao;
import com.yenlien.traceyun.control.dao.LoanInfoDao;
import com.yenlien.traceyun.control.dao.RepaymentDao;
import com.yenlien.traceyun.control.entity.BankInfo;
import com.yenlien.traceyun.control.entity.BankLevel;
import com.yenlien.traceyun.control.entity.LoanInfo;
import com.yenlien.traceyun.control.entity.Repayment;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;

/**
 * 借款信息
 */
@Service
public class LoanInfoService {
    @Autowired
    private BankInfoDao bankInfoDao;

    @Autowired
    private BankLevelDao bankLevelDao;

    @Autowired
    private LoanInfoDao loanInfoDao;

    @Autowired
    private RepaymentDao repaymentDao;

    /**
     * 申请贷款,审核还款信息
     */
    public Object applyInfo(LoanInfo loanInfo) {
        if (StringUtils.isNotEmpty(loanInfo.getId())) {
            loanInfoDao.delete(loanInfo);
        }
        loanInfo.setCreateTime(new Date());
        return loanInfoDao.save(loanInfo);
    }

    /**
     * 根据ID查询单个详情
     */

    public Object findById(String id) {
        List<Map<String, Object>> li = loanInfoDao.findById(id);
        LoanInfo loanInfo = new LoanInfo();
        if (li.size() > 0 && li.get(0) != null) {
            loanInfo.setId(li.get(0).get("id").toString());
            loanInfo.setName(li.get(0).get("name").toString());
            loanInfo.setIdCard(li.get(0).get("id_card").toString());
            loanInfo.setCreateTime((Date) li.get(0).get("create_time"));
            loanInfo.setBusinessLicenseNum(li.get(0).get("business_license_num").toString());
            loanInfo.setBankName(li.get(0).get("bankName").toString());
            loanInfo.setImgPath(li.get(0).get("img_path") != null ? li.get(0).get("img_path").toString() : "");
            loanInfo.setAmount((BigDecimal) li.get(0).get("amount"));
            loanInfo.setBranchBankName(li.get(0).get("branchBankName").toString());
            loanInfo.setGuaranteeCompanyName(li.get(0).get("guarantee_company_name").toString());
            loanInfo.setGuaranteeCompanyLegalPerson(li.get(0).get("guarantee_company_legal_person").toString());
            loanInfo.setGuaranteeCompanyLegalPersonIdCard(li.get(0).get("guarantee_company_legal_person_id_card").toString());
            loanInfo.setLoanPeriod((int) li.get(0).get("loan_period"));
            loanInfo.setRemarks(li.get(0).get("remarks").toString());
            loanInfo.setStatus(li.get(0).get("status").toString());
            loanInfo.setPid(li.get(0).get("pid").toString());
            loanInfo.setBankInfoId(li.get(0).get("bank_info_id").toString());
            loanInfo.setCompanyId(li.get(0).get("company_id") != null ? li.get(0).get("company_id").toString() : "");


            loanInfo.setContactsPeople(li.get(0).get("contacts_people") != null ? li.get(0).get("contacts_people").toString() : "");
            loanInfo.setContactsTel(li.get(0).get("contacts_tel") != null ? li.get(0).get("contacts_tel").toString() : "");
            loanInfo.setMortgage(li.get(0).get("mortgage") != null ? li.get(0).get("mortgage").toString() : "");
            loanInfo.setMortgageValue(li.get(0).get("mortgage_value") != null ? li.get(0).get("mortgage_value").toString() : "");
            loanInfo.setLegalPerson(li.get(0).get("legal_person") != null ? li.get(0).get("legal_person").toString() : "");
            loanInfo.setArea(li.get(0).get("area") != null ? (BigDecimal) li.get(0).get("area") : new BigDecimal(0.00));
            loanInfo.setPosition(li.get(0).get("position") != null ? li.get(0).get("position").toString() : "");
            loanInfo.setSpecies(li.get(0).get("species") != null ? li.get(0).get("species").toString() : "");
            loanInfo.setTerm(li.get(0).get("term") != null ? (int) li.get(0).get("term") : 0);
            loanInfo.setPurpose(li.get(0).get("purpose") != null ? li.get(0).get("purpose").toString() : "");
            loanInfo.setUsufruct(li.get(0).get("usufruct") != null ? li.get(0).get("usufruct").toString() : "");
            loanInfo.setLandNum(li.get(0).get("land_num") != null ? li.get(0).get("land_num").toString() : "");

            loanInfo.setIdCardJustImg(li.get(0).get("id_card_just_img") != null ? li.get(0).get("id_card_just_img").toString() : "");
            loanInfo.setIdCardBackImg(li.get(0).get("id_card_back_img") != null ? li.get(0).get("id_card_back_img").toString() : "");
            loanInfo.setApplyImg(li.get(0).get("apply_img") != null ? li.get(0).get("apply_img").toString() : "");
            loanInfo.setBusinessImg(li.get(0).get("business_img") != null ? li.get(0).get("business_img").toString() : "");
            loanInfo.setNaturalImg(li.get(0).get("natural_img") != null ? li.get(0).get("natural_img").toString() : "");
            loanInfo.setProveImg(li.get(0).get("prove_img") != null ? li.get(0).get("prove_img").toString() : "");
            loanInfo.setSharesImg(li.get(0).get("shares_img") != null ? li.get(0).get("shares_img").toString() : "");

            loanInfo.setRate(li.get(0).get("rate") != null ? li.get(0).get("rate").toString() : "");
            loanInfo.setMonthlyAmount(li.get(0).get("monthly_amount") != null ? li.get(0).get("monthly_amount").toString() : "");
        }
        return loanInfo;
    }

    /**
     * 查询所有
     */
    public Page<LoanInfo> findByList(final LoanInfo loanInfo) {
        Pageable pageable = PageRequest.of(loanInfo.getPage(), loanInfo.getPageSize(), Sort.Direction.DESC, "createTime");
        Page<LoanInfo> all = loanInfoDao.findAll(new Specification<LoanInfo>() {
            private static final long serialVersionUID = -1396496630802017658L;

            @Override
            public Predicate toPredicate(Root<LoanInfo> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                //构造查询条件
                List<Predicate> list = new ArrayList<>();
                if (!StringUtils.isEmpty(loanInfo.getName())) {
                    list.add(cb.equal(root.get("name"), loanInfo.getName()));        //根据传的状态筛选
                }
                if (StringUtils.isNotEmpty(loanInfo.getStatus())) {
                    list.add(cb.equal(root.get("status"), loanInfo.getStatus()));        //根据传的状态筛选
                }
                if (StringUtils.isNotEmpty(loanInfo.getBankInfoId())) {
                    list.add(cb.equal(root.get("bankInfoId"), loanInfo.getBankInfoId()));        //根据传的状态筛选
                }
                if (StringUtils.isNotEmpty(loanInfo.getCompanyId())) {
                    list.add(cb.equal(root.get("companyId"), loanInfo.getCompanyId()));
                }
                Predicate[] predicate = new Predicate[list.size()];
                return cb.and(list.toArray(predicate));
            }
        }, pageable);
        List<LoanInfo> content = all.getContent();
        List<LoanInfo> li = new ArrayList<>();
        for (LoanInfo info : content) {
            BankInfo bank = bankInfoDao.findById(info.getBankInfoId());
            if (bank != null) {
                info.setBankName(bank.getName());
            }
            li.add(info);
        }
        Page<LoanInfo> infoPage = new PageImpl<LoanInfo>(li, pageable, all.getTotalElements());
        return infoPage;
    }

    /**
     * 查询银行层级
     */
    public Object bankInfo() {
        List<BankLevel> all = bankLevelDao.findAll();
        JSONArray secondList = new JSONArray();
        for (BankLevel bankLevel : all) {
            JSONObject obj = new JSONObject();
            obj.put("id", bankLevel.getId());
            obj.put("alias", bankLevel.getAlias());
            obj.put("name", bankLevel.getName());
            obj.put("imgPath", bankLevel.getImgPath());
            List<BankInfo> bankInfo = bankInfoDao.findByPid(bankLevel.getId());     //支行
            obj.put("bankInfo", bankInfo);
            secondList.add(obj);
        }
        return secondList;
    }

    /**
     * 更新申请信息状态
     */
    public Object updateStatus(LoanInfo loanInfo) {
        String status = loanInfo.getStatus();
        String id = loanInfo.getId();
        if (status.equals("-1")) {
            return loanInfoDao.updateStatus(id, status, new Date());            //拒绝
        }
        return loanInfoDao.updateStatus2(id, status, new Date(), loanInfo.getRate(), loanInfo.getAmount());            //通过

    }

    /**
     * 银行端   我的客户列表查询,根据companyId 搜索
     */
    public Page<LoanInfo> findByCustomer(final LoanInfo loanInfo) {
        Pageable pageable = PageRequest.of(loanInfo.getPage(), loanInfo.getPageSize(), Sort.Direction.DESC, "createTime");
        Page<LoanInfo> all = loanInfoDao.findAll(new Specification<LoanInfo>() {
            private static final long serialVersionUID = -1396496630802017658L;

            @Override
            public Predicate toPredicate(Root<LoanInfo> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                //构造查询条件
                List<Predicate> list = new ArrayList<>();
                if (!StringUtils.isEmpty(loanInfo.getName())) {
                    list.add(cb.equal(root.get("name"), loanInfo.getName()));        //根据传的状态筛选
                }
                if (StringUtils.isNotEmpty(loanInfo.getStatus())) {
                    list.add(cb.equal(root.get("status"), loanInfo.getStatus()));        //根据传的状态筛选
                }
                if (StringUtils.isNotEmpty(loanInfo.getBankInfoId())) {
                    list.add(cb.equal(root.get("bankInfoId"), loanInfo.getBankInfoId()));        //根据传的状态筛选
                }
                if (StringUtils.isNotEmpty(loanInfo.getCompanyId())) {
                    list.add(cb.equal(root.get("companyId"), loanInfo.getCompanyId()));
                }
                Predicate[] predicate = new Predicate[list.size()];
                return cb.and(list.toArray(predicate));
            }
        }, pageable);

        List<LoanInfo> li = all.getContent();
        List<LoanInfo> lis = new ArrayList<>();
        for (LoanInfo info : li) {
            List<Repayment> repay = repaymentDao.findByLoanId(info.getId());
            if (repay.size() > 0 && repay.get(0) != null) {
                info.setSurplusAmount(repay.get(0).getSurplusAmount());       //剩余还款金额
                info.setSurplusNum(repay.get(0).getRepaymentNum());  //剩余还款周期
            }
            lis.add(info);

        }
        Page<LoanInfo> infoPage = new PageImpl<LoanInfo>(lis, pageable, all.getTotalElements());
        return infoPage;
    }

    /**
     * 我的客户    根据ID查询单个
     */
    public Object findByIdCustomer(String id) {
        List<Map<String, Object>> map = loanInfoDao.findByIdCustomer(id);
        if (map.size() > 0) {
            List<Repayment> id1 = repaymentDao.findByLoanId(map.get(0).get("id").toString());
            for (Map<String, Object> mp : map) {
                Map<Object, Object> map1 = new HashMap<>(mp);
                Repayment pay = id1.get(0);
//                map1.put("surplusAmount", pay.getSurplusAmount());          //剩余还款金额
                map1.put("surplusNum", pay.getSurplusNum());            //剩余周期
                map1.put("surplusAmount", pay.getSurplusAmount());                 //剩余应还金额

                Date repaymentTime = pay.getRepaymentTime();
                int day = repaymentTime.getDate();
                map1.put("repaymentTime", "每月" + day + "日");     //还款时间
                map1.put("rate", pay.getRate());                 //利率
                return map1;
            }
        } else {
            List<Map<String, Object>> li = loanInfoDao.findById2(id);
            Map<String, Object> map2 = li.get(0);
            return map2;
        }
        return null;
    }

    /**
     * 合作社 or 银行    贷款管理列表查询
     */
    public Page<LoanInfo> findByIdrepayment(final LoanInfo loanInfo) {
        Pageable pageable = PageRequest.of(loanInfo.getPage(), loanInfo.getPageSize(), Sort.Direction.DESC, "createTime");
        Page<LoanInfo> all = loanInfoDao.findAll(new Specification<LoanInfo>() {
            private static final long serialVersionUID = -1396496630802017658L;

            @Override
            public Predicate toPredicate(Root<LoanInfo> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                //构造查询条件
                List<Predicate> list = new ArrayList<>();
                if (!StringUtils.isEmpty(loanInfo.getName())) {
                    list.add(cb.equal(root.get("name"), loanInfo.getName()));        //根据传的状态筛选
                }
                if (StringUtils.isNotEmpty(loanInfo.getStatus())) {
                    list.add(cb.equal(root.get("status"), loanInfo.getStatus()));        //根据传的状态筛选
                }
                if (StringUtils.isNotEmpty(loanInfo.getBankInfoId())) {
                    list.add(cb.equal(root.get("bankInfoId"), loanInfo.getBankInfoId()));        //根据传的状态筛选
                }


                if (StringUtils.isNotEmpty(loanInfo.getCompanyId())) {
                    list.add(cb.equal(root.get("companyId"), loanInfo.getCompanyId()));
                }
                list.add(cb.equal(root.get("status"), "1"));        //根据传的状态筛选
                Predicate[] predicate = new Predicate[list.size()];
                return cb.and(list.toArray(predicate));
            }
        }, pageable);
        List<LoanInfo> content = all.getContent();
        List<LoanInfo> li = new ArrayList<>();
        for (LoanInfo info : content) {
            BankInfo bank = bankInfoDao.findById(info.getBankInfoId());
            if (bank != null) {
                info.setBankName(bank.getName());
            }
            li.add(info);
        }
        List<LoanInfo> li2 = new ArrayList<>();
        for (LoanInfo info : li) {
            String id = info.getId();
            Integer surpluAamount = repaymentDao.findByLoanId2(id);           //已还金额
            info.setRepaidAmount(surpluAamount != null ? new BigDecimal(surpluAamount) : new BigDecimal(0));
            List<Repayment> byLoanId = repaymentDao.findByLoanId3(id);
            if (byLoanId.size() > 0 && byLoanId.get(0) != null) {
                Repayment repayment = byLoanId.get(0);
                info.setSurplusNum(Integer.toString(repayment.getSurplusNum() + 1));          //剩余期数
                info.setSurplusAmount(repayment.getSurplusAmount());        //剩余还款金额
                Date repaymentTime = repayment.getRepaymentTime();
                int day = repaymentTime.getDate();
                info.setRepaymentTime("每月" + day + "日");
                info.setRealAmount(repayment.getAmount());          //本期还款金额
            }
            li2.add(info);
        }
        Page<LoanInfo> infoPage = new PageImpl<LoanInfo>(li2, pageable, all.getTotalElements());
        return infoPage;
    }


    /**
     * 合作社 or 银行    贷款管理根据ID查询单个
     */
    public Object findIdRepay(String id) {
        LoanInfo loan = new LoanInfo();
        List<Map<String, Object>> byId = loanInfoDao.findById(id);
        if (byId.size() > 0 && byId.get(0) != null) {
            Map<String, Object> map = byId.get(0);

            List<Repayment> li = repaymentDao.findByLoanId3(id);
            if (li.size() > 0 && li.get(0) != null) {

                Repayment repayment = li.get(0);
                loan.setId(map.get("id").toString());
                loan.setName(map.get("name") != null ? map.get("name").toString() : "");      //申请人
                loan.setUpdateTime(repayment.getCreateTime());          //放款时间
                loan.setGuaranteeCompanyName(map.get("guarantee_company_name") != null ? map.get("guarantee_company_name").toString() : "");            //担保公司
                loan.setBankName(map.get("bankName") != null ? map.get("bankName").toString() : "");      //放款银行
                loan.setRemarks(map.get("remarks") != null ? map.get("remarks").toString() : "");     //用途
                loan.setLoanPeriod(map.get("loan_period") != null ? Integer.valueOf(map.get("loan_period").toString()) : 0);        //还款周期
                loan.setMortgageValue(map.get("mortgage_value") != null ? map.get("mortgage_value").toString() : "");           //抵押品价值
                loan.setAmount(map.get("amount") != null ? new BigDecimal(map.get("amount").toString()) : new BigDecimal(0));     //申请金额
                Date repaymentTime = repayment.getRepaymentTime();
                int day = repaymentTime.getDate();
                loan.setRepaymentTime("每月" + day + "日");        //还款时间
                loan.setSurplusNum(Integer.toString(repayment.getSurplusNum() + 1)); //剩余期数
                loan.setSurplusAmount(repayment.getSurplusAmount());        //剩余还款金额
                Integer byTotalAmout = repaymentDao.findByTotalAmout(id);
                loan.setTotalAmount(byTotalAmout != null ? new BigDecimal(byTotalAmout) : new BigDecimal(0));     //还款总额
            }
            return loan;
        }
        return null;
    }
}

